 //  Copyright(c) 2020 lutianming email：641471957@qq.com
var website_host = function(){if (window.location.href.substring(0,4) == "file"){return "http://172.29.81.28:1080";}return ".";};
var http_post = function(uri, json_data, success_callback, error_callback){
  $.ajax({type: "post", url: website_host() + uri, data: JSON.stringify(json_data), dataType: "json", success: success_callback, error: error_callback});
}
var ProjectConfig = []
var CaseCache = {}
var ReportTemplate = null
var KeydownCallback = null
var QueryParms = {project:0, nav:"task", case:"record"}

function init(){
  var query_str = window.location.search.replace('?', '');
  var query_array = query_str.split("&")
  for (var i = 0; i < query_array.length; i++){
    var item = query_array[i].split("=")
    if (item.length > 1){
      QueryParms[item[0]] = item[1]
    }
  }
  $(document).bind("keydown", function(e){ if (KeydownCallback){ return KeydownCallback(e)}})
  $.ajax({ type: "get", url: website_host() + "/report_template", success: function(data){ ReportTemplate = data}});
  $("#ProjectSelect").change(function(){
    QueryParms.project = Number($("#ProjectSelect").val())
    $(".project_select").val(QueryParms.project)
    $(".project_select").change()
    history.replaceState(null, "", '?project=' + QueryParms.project + '&nav=' + QueryParms.nav + '&case=' + QueryParms.case);
  })

  http_post("/api/project_config", {}, 
    function(content){
      ProjectConfig = content.data
      var project = null
      for (i = 0; i < ProjectConfig.length; i++){
        project = ProjectConfig[i]
        var temp = {}
        var parms =  project.parms.split(";")
        for (j = 0; j < parms.length; j++){
          var parm = parms[j].split(":")
          var key = parm[0]
          if (key == ""){
            continue
          }
          var value = parm[1]
          if (value == "bool"){
            temp[key] = {"type":"bool"}
          }
          else if (value == "text"){
            temp[key] = {"type":"text"}
          }
          else{
            temp[key] = {"type":"select"}
            temp[key].opetion = value.split(",")
          }
        }
        project.parms = temp
      }
      $("#ProjectSelect").html(show_project_select())
      run()
    },
    run
  );
}

function get_project_config(project_id){
  var project = null
  for (var i = 0; i < ProjectConfig.length; i++){
    if (ProjectConfig[i].id == project_id){
      project = ProjectConfig[i]
    }
  }
  return project
}

function show_project_select(project_name){
  var row = ""
  for (var i = 0; i < ProjectConfig.length; i++){
    var project = ProjectConfig[i]
    row += '<option value ="'+ project.id+'"'+ (project_name == project.name || QueryParms.project == project.id ? " selected" : "") +'>'+project.name+'</option>'
  }
  return row;
}

function run(){
	subcontent_back_connect_click();
	nav_click(QueryParms.nav);
  setInterval(gloabl_timer, 10000)
	$(".nav").click(function(){
		QueryParms.nav = $(this).attr("id");
		if (QueryParms.nav == "download")
		return;
    $("bhead").empty();
    $("#list").empty();
    $("bhead").show();
    $("#list").show();
    $("#subcontent").hide();
    $("float_window").hide()
    KeydownCallback = null;
		nav_click(QueryParms.nav);
	});
}

function nav_click(nav){
  if (nav == "task"){
    click_nav_task();
  }
  else if (nav == "case"){
    click_nav_case();
  }
  else if (nav == "report"){
    click_nav_report();
  }
  else if (nav == "proxy"){
    click_nav_proxy();
  }
  else if (nav == "agent"){
    click_nav_agent();
  }
  else if (nav == "about"){
    click_nav_about();
  }
  else{
    QueryParms.nav = "task"
    click_nav_task();
  }
  history.replaceState(null, "",'?project='+ QueryParms.project + '&nav=' + QueryParms.nav + '&case=' + QueryParms.case);
  }


/*公共函数*/
function timestampToTime(timestamp) {
  var date = new Date(timestamp);
  var Y = date.getFullYear() + '-';
  var M = (date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1) + '-';
  var D = (date.getDate() < 10 ? '0'+date.getDate() : date.getDate()) + ' ';
  var h = (date.getHours() < 10 ? '0'+date.getHours() : date.getHours()) + ':';
  var m = (date.getMinutes() < 10 ? '0'+date.getMinutes() : date.getMinutes()) + ':';
  var s = (date.getSeconds() < 10 ? '0'+date.getSeconds() : date.getSeconds());
  var strDate = Y+M+D+h+m+s;
  return strDate;
}

function subcontent_back_connect_click(){
  $("#subcontent_back").click(function(){
    $("bhead").show();
    $("#list").show();
    $("#subcontent").hide();
    $("#subdetail").empty();
    $("float_window").hide()
    KeydownCallback = null;
  });
}

function subcontent_show(){
  $("bhead").hide();
  $("#list").hide();
  $("#subcontent").show();
  $("suboption").empty();
}
/*公共函数*/


/*定时器*/
function gloabl_timer(){
  if (QueryParms.nav == "task"){
    var flag = $("#list").is(":visible")
    if (flag){
      show_task_flush()
    }
  }
  else if (QueryParms.nav == "case"){
    if ($("#record_flag").text() == "关闭"){
      show_record_default()
    }
  }
  else if (QueryParms.nav == "proxy"){
  }
  else if (QueryParms.nav == "agent"){
    show_agent_list_flush()
  }
  else if (QueryParms.nav == "about"){
  }
}
/*定时器*/

/*任务管理 */
var task_list_data = {}

function click_nav_task(){
  $("bhead").append('\
  此处管理压力测试任务，添加、删除、增减任务人数、开启或停止。</br></br>\
  <table width=100%><tr valign="top"><td width=40%><div id="tasklable">编号：<a id="task_id"></a></div>\
  说明：<input id="des" type="text" placeholder="请输入任务描述" style="width:370"></br>\
  项目：<select id="project" class="project_select" title="请通过顶部切换项目" disabled></select></br>\
  <ttl title="每次启动x人，间隔y秒，直到启动人数达到总人数">总人数：<input id="total_user" type="text" placeholder="总人数" style="width:65;height:22">&emsp;\
  单次启动：<input id="once_user" type="text" placeholder="人数" style="width:60">&emsp;\
  间隔：<input id="space_time" type="text" placeholder="1秒" style="width:60"></ttl></br>\
  循环：<select id="loop" title="是：单个用户用例执行结束将从头开始执行\n否：单个用户用例执行结束即停止\n实时回放：用户永远在等待新用例步骤下发，不会停止执行">\
      <option value ="1">否</option>\
      <option value ="0">是</option>\
      <option value ="2">实时回放</option>\
    </select>\
    <input id="ignor_err" type="checkbox" value="" hidden><a id="ignor_text" title="循环模式下用户因错误终止，勾选则重新开始，否则停止执行" hidden>忽略错误</a></br>\
  用例：\
  <select id="case_dir">\
  <option value="record" '+ (QueryParms.case == "record"?'selected':'') +'>录制</option>\
  <option value="http" '+ (QueryParms.case == "http"?'selected':'') +'>Http</option>\
  </select>\
  <select id="case_file" style="width:310"></select></br>\
  回放端口：<font size="1">(*勾选需要的数据,输入框可以重定向地址)</font><div style="width:90%;height:83px;overflow:auto;overflow-x:hidden;"><table id="replay" width=100%></table></div>\
  </br>&nbsp;<bt id="add_task">添加</bt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<bt id="task_modify" hidden>修改</bt>\
  </td><td>\
    <div>运行日志输出：<select id="log_level" title="日志输出等级">\
      <option value="0">TRACE</option>\
      <option value="1">DEBUG</option>\
      <option value="2" selected>NORMAL</option>\
      <option value="3">ERROR</option>\
      <option value="4">FAULT</option>\
      <option value="5">NONE</option>\
    </select><ttl title="任务运行结束负载端将日志上传到控制端task_log目录"><input id="log_report" type="checkbox">日志回收</ttl><br/></div>\
    <div title="用户定时器的执行间隔时间，根据不同项目需求进行配置。\n如KCP通讯中可以设置为10-20毫秒，一般情况下为100-200毫秒，适当的数据可以达到最佳并发效果">\
    用户执行周期：<input id="user_execute_cycle" type="text" value="200" placeholder="毫秒" style="width:120"></ttl>&nbsp毫秒</br></div>\
    <div title="任务附加参数\n自定义：可自由输入\n预定义：在sheeps.ini中配置,例a:bool;b:text;c:1,2,3">\
  附加参数：<br/>&nbsp&nbsp[自定义]：<input id="parms" type="text" placeholder="格式：a&b=1&c=hello" style="width:360"></br>&nbsp&nbsp[预定义]：<br/>&nbsp&nbsp&nbsp&nbsp\
  <table id="define_parms" style="display:inline"></table><br/>\
  </div></td></tr></table>')

  $("#project").append(show_project_select());
  show_task_project_parms({})
  $("#project").change(function(){
    show_task_project_parms({})
  })

  $("#loop").change(function(){
    var value = $("#loop").val()
    if (value == 1){
      $("#ignor_err").hide();
      $("#ignor_err").prop("checked",false);
      $("#ignor_text").hide();
    }
    else{
      $("#ignor_err").show();
      $("#ignor_text").show();
    }
  });

  
  $("#case_dir").change(function(){
    var case_dir = $("#case_dir").val()
    QueryParms.case = case_dir
    history.replaceState(null, "",'?project='+ QueryParms.project + '&nav=' + QueryParms.nav + '&case=' + QueryParms.case);
    $("#case_file").empty();
    $("#replay").empty()
    http_post("/api/case_list", {"case_dir": case_dir},
      function(content){
        var array = content.data;
        if (array.length == 0){
          return;
        }
        var row = ""
        for (i = 0; i < array.length; i++){
          var item = array[i];
          row += '<option value ="'+ item.case_file+'">'+item.des+' ['+item.case_file+']</option>'
        }
        $("#case_file").append(row);
        CaseCache[$("#case_dir").val()] = row
        show_task_select_dbfile_record($("#case_dir").val(),$("#case_file").val(), false)
      }
    );
  });
  $("#case_file").change(function(){
    show_task_select_dbfile_record($("#case_dir").val(), $("#case_file").val(), false);
  });

  $("#add_task").click(function(){
    show_task_add_or_modify_call(false);
  });
  $("#task_modify").click(function(){
    show_task_add_or_modify_call(true);
  });
  
  $("#case_dir").change()
  show_task_flush();
}

function show_task_project_parms(default_values){
  var project_id = $("#project").val()
  var project = get_project_config(Number(project_id))
  var parms =  project.parms
  var row = ""
  for (var key in parms){
    var default_value = ""
    var value = parms[key]
    if (value.type == "bool"){
      if (default_values[key] != null){
        default_value = "checked"
      }
      row += '<tr><td>'+key+'</td><td>:</td><td><input type="checkbox" value="" '+default_value+'></input></td></tr>'
    }
    else if (value.type == "text"){
      if (default_values[key] != null){
        default_value = default_values[key]
      }
      row += '<tr><td>'+key+'</td><td>:</td><td><input type="text" value="'+default_value+'"></input></td></tr>'
    }
    else {
      var opetion = ""
      for (var j = 0; j < value.opetion.length; j++){
        if (default_values[key] == value.opetion[j]){
          default_value = " selected"
        }
        opetion += '<option'+default_value+'>'+value.opetion[j]+'</option>'
        default_value = ""
      }
      row += '<tr><td>'+key+'</td><td>:</td><td><select>'+opetion+'</select></td></tr>'
    }
  }
  $("#define_parms").html(row)
}

function show_task_select_dbfile_record(case_dir, case_file, array2){
  http_post("/api/case_addr_list", {"case_dir":case_dir,"case_file":case_file},
    function(content){
      var row = ""
      var array = content.data.record_list;
      for (i = 0; i < array.length; i++){
        var item = array[i];
        var flag = false;
        var j = 0;
        var dst = ""
        if (array2 == false) {
          flag = true
        }
        else{
          for (j = 0; j < array2.length; j++){
            var item2 = array2[j];
            if (item2.src == item.addr){
              flag = true;
              dst = item2.dst
              break;
            }
          }
        }
        
        row += '<tr><td nowrap="nowrap" width=20%><input class="replay_addr" type="checkbox" value="' + i + '"' + (flag?' checked':'') + '>\
        <a id="replay_src'+i+'">'+item.addr+'</a></td><td>-><input id="replay_dst'+i+'" type="text" placeholder="重定向，例：127.0.0.1:8080" value="'+ (flag ? dst : "")+'"></td></tr>'
      }
      $("#replay").html(row);
    }
  );
}

function show_task_add_or_modify_call(moddify){
  var des = $("#des").val()
  var projectid = Number($("#project").val())
  var total_user = Number($("#total_user").val())
  var once_user = Number($("#once_user").val())
  var space_time = Number($("#space_time").val())
  var loop = Number($("#loop").val())
  var ignor_err = Number($("#ignor_err").prop("checked"))
  var log_level = Number($("#log_level").val())
  var log_report = Number($("#log_report").prop("checked"))
  var parms = $("#parms").val()
  var case_dir = $("#case_dir").val()
  var case_file = $("#case_file").val()
  var user_execute_cycle = Number($("#user_execute_cycle").val())
  if (total_user == 0 || isNaN(total_user) || once_user == 0 || isNaN(once_user) || space_time == 0 || isNaN(space_time) || 
  user_execute_cycle == 0 || isNaN(user_execute_cycle) || case_dir == null || case_file == null ){
    alert("参数错误")
    return;
  }

  var define_parms = []
  $("#define_parms tbody tr").each(function(){
    var row = $(this).children()
    var key = row[0].innerText
    var value = row.next().next().children()
    if (value.is("input")){
      if (value.attr("type") == "checkbox"){
        if ( value.prop("checked")){
          define_parms.push(key)
        }
      }
      else{
        var content = value.val()
        if (content != ""){
          define_parms.push(key + "=" + content)
        }
      }
    }
    else {
      var content = value.val()
      if (content != ""){
        define_parms.push(key + "=" + content)
      }
    }
  })
  if (parms != ""){
    define_parms.push(parms)
  }
  parms = define_parms.join("&")

  var jsondata = {"des":des, "user_execute_cycle":user_execute_cycle,"project_id":projectid,"total_user":total_user,"once_user":once_user,"space_time":space_time,"loop_mode":loop,"ignor_error":ignor_err,
  "log_level":log_level, "log_report":log_report,"parms":parms,"parms2":"","case_dir":case_dir,"case_file":case_file};
  jsondata["replay"] = [];
  $(".replay_addr:checked").each(function(index, item){
    var reitem = {"src": $("#replay_src"+$(this).val()).text()};
    var dst = $("#replay_dst" + $(this).val()).val();
    dst = dst.replace(/\s*/g, '');
    if (dst != ""){
      reitem["dst"] = dst;
    }
    jsondata["replay"].push(reitem);
  });
  if (moddify){
    jsondata["task_id"]=Number($("#task_id").text());
  }
  else{
    jsondata["group_id"] = "默认"
    // jsondata["log_level"] = 2
    // jsondata["log_report"] = 0
  }
  http_post("/api/task_create", jsondata, show_task_flush)
}

function show_task_flush(){
  http_post("/api/task_list", {}, show_task_list)
}

function show_task_list(content){
  if (QueryParms.nav != "task"){
    return
  }
  var row = "<thead><tr><td>编号</td><td>状态</td><td>项目</td><td>说明</td><td>人数(总/剩/活)</td><td>单次(人)</td><td>间隔(秒)</td><td>循环</td><td>执行组</td><td>日志</td><td>操作</td><td>报表</td></tr></thead>"
  var array = content.data
  if (array.length == 0){
    return
  }
  task_list_data = {}
  for (var i = 0; i < array.length; i++){
    var item = array[i]
    task_list_data[item.task_id] = item
    var state_text = "未开始"
    if (item.state == 1){state_text = "运行中"}
    else if(item.state == 2){state_text = "正在结束"}
    else if (item.state == 3) { state_text = "停止" }
    var runing = item.state == 1 || item.state == 2 ? "停止" : "开始"
    var loop = "否"
    if (item.loop_mode == 0){
      loop = "是"
      if (item.ignor_error == true) {
        loop = "是(忽略错误)"
      }
    }else if(item.loop_mode == 2){
      loop = "实时回放"
    }

    var project_cfg = get_project_config(item.project_id)
    var groupids = project_cfg.group_ids
    var groupindex = groupids.indexOf(item.group_id)
    var group = '<td width="70"><select class="groupid">'
    for (j = 0; j < groupids.length; j++){
      group += '<option value="'+groupids[j]+'"'+(j == groupindex?" selected>":">")+groupids[j]+'</option>'
    }
    if (groupindex < 0){
      group += '<option value="'+item.group_id+'" selected>'+item.group_id+'</option>'
    }
    group += '</select></td>'

    var log_level = item.log_level
    var log_level_str = ["TRACE", "DEBUG", "NORMAL", "ERROR", "FAULT", "NONE"]
    var log = '<td width=100><select class="loglevel" style="width:80">'
    for (var j = 0; j < log_level_str.length; j++){
      log += '<option value ="'+j+'"'+(j == log_level?" selected>":">")+log_level_str[j]+'</option>'
    }
    log += '</select></td>'
    row += '<tr><td width=40>'+item.task_id+'</td>\
      <td width=80>'+ state_text +'</td>\
      <td width=80>'+item.project_name+'</td>\
      <td width=250>'+item.des+'</td>\
      <td width=150>'+item.total_user+"/"+item.left_user+"/"+item.online+'</td>\
      <td width=70>'+item.once_user+'</td>\
      <td width=70>'+item.space_time+'</td>\
      <td width=100>'+loop+'</td>'
      + group + log +
      '<td width=180><bt class="task_start">'+ runing +'</bt>\
        <bt class="task_modify_button"'+action_hide(item, 1)+'>编辑</bt>\
        <input type="text" style="width:60"'+action_hide(item, 2)+'>\
        <bt class="task_user"'+action_hide(item, 2)+'>增加人数</bt>\
        <bt class="task_delete"'+action_hide(item, 3)+'>删除</bt></td>\
      <td><bt class="task_report">查看📈</bt></td>\
      </tr>'
  }
  $("#list").html(row)

  show_task_group_chang()
  show_task_log_level_chang()
  show_task_start()
  show_task_modify_button_click()
  show_task_user()
  show_task_delete()
  show_task_report()
}

function action_hide(item, action_type) {
  if (item.state == 1 || item.state == 2) {
    if (action_type == 1 || action_type == 3){  
      return " hidden"
    }
  }else{
    if (action_type == 2){
      return " hidden"
    }
  }
  return ""
}

function show_task_group_chang(){
  $(".groupid").change(function(){
    var tr_obj = $(this).parent().parent()
    var task_id = Number(tr_obj.find("td:first").text())
    var group_id = $(this).val()
    var jsondata = {"task_id":task_id,"group_id":group_id}
    http_post("/api/task_group", jsondata, null)
  });
}

function show_task_log_level_chang(){
  $(".loglevel").change(function(){
    var tr_obj = $(this).parent().parent()
    var task_id = Number(tr_obj.find("td:first").text())
    var loglevel = Number($(this).val())
    var jsondata = {"task_id":task_id,"log_level":loglevel}
    http_post("/api/task_log_level", jsondata, null)
  });
}

function show_task_start(){
  $(".task_start").click(function(){
    var tr_obj = $(this).parent().parent()
    var taskid_obj = tr_obj.find("td:first")
    var edite_obj = $(this).next()
    var add_user_input_obj = edite_obj.next()
    var add_user_button_obj = add_user_input_obj.next()
    var delete_obj = add_user_button_obj.next()
    var api = "";
    if ($(this).text() == "开始"){
      $(this).text("停止");
      taskid_obj.next().text("运行中")
      edite_obj.hide();
      add_user_input_obj.show();
      add_user_button_obj.show();
      delete_obj.hide();
      api = "/api/task_run"
    }
    else{
      $(this).text("开始");
      taskid_obj.next().text("停止")
      edite_obj.show();
      add_user_input_obj.hide();
      add_user_button_obj.hide();
      delete_obj.show();
      api="/api/task_stop";
    }
    var task_id = Number(taskid_obj.text())
    var jsondata = {"task_id":task_id};
    http_post(api, jsondata, null)
  });
}

function show_task_modify_button_click(){
  $(".task_modify_button").click(function () {
    var tr_obj = $(this).parent().parent()
    var task_id = Number(tr_obj.find("td:first").text())
    var jsondata = {"task_id":task_id};
    http_post("/api/task_info", jsondata,
      function(content){
        var info = content.data;
        $("#task_id").text(info.task_id);
        //$("#tasklable").show();
        $("#des").val(info.des);
        $("#project").val(info.project_id);
        $("#total_user").val(info.total_user);
        $("#once_user").val(info.once_user);
        $("#space_time").val(info.space_time);
        $("#loop").val(info.loop_mode);
        $("#ignor_err").prop("checked",info.ignor_error);
        if (info.loop_mode == 0){
          $("#ignor_err").show()
        }
        $("#case_dir").val(info.case_dir);
        $("#case_file").empty();
        $("#case_file").append(CaseCache[info.case_dir])
        $("#case_file").val(info.case_file);
        $("#replay").empty();

        $("#log_level").val(info.log_level);
        $("#log_report").prop("checked", info.log_report);
        show_task_select_dbfile_record(info.case_dir, info.case_file, info.replay)

        $("#user_execute_cycle").val(info.user_execute_cycle)
        var project = get_project_config(info.project_id)
        var define = {}
        var ndefine = []
        var define_parms = info.parms.split("&")
        for (i = 0; i < define_parms.length; i++){
          var kv = define_parms[i].split("=")
          if (project.parms[kv[0]] != null){
            define[kv[0]] = kv[1] || true
          }
          else{
            ndefine.push(define_parms[i])
          }
        }
        $("#parms").val(ndefine.join("&"))
        show_task_project_parms(define)
        $("#task_modify").show();
      }
    );
  });
}

function show_task_user(){
  $(".task_user").click(function(){
    var tr_obj = $(this).parent().parent()
    var task_id = Number(tr_obj.find("td:first").text())
    var user_connt = Number($(this).prev().val())
    if (user_connt ==0 || isNaN(user_connt)){return;}
    var jsondata = {"task_id":task_id,"user_count":user_connt};
    http_post("/api/task_user", jsondata, show_task_flush)
  });
}

function show_task_delete(){
  $(".task_delete").click(function(){
    var tr_obj = $(this).parent().parent()
    var id_obj = tr_obj.find("td:first")
    var task_id = Number(id_obj.text())
    var des = id_obj.next().next().next().text()
    var flag = confirm('删除任务:\n#'+task_id+':'+des+'\n\n是否继续？')
    if (flag){
      tr_obj.remove()
      var jsondata = {"task_id":task_id}
      http_post("/api/task_delete", jsondata, show_task_flush)
    }
  });
}

function show_task_report(){
  $(".task_report").click(function(){
    var tr_obj = $(this).parent().parent()
    var td_obj = tr_obj.find("td:first")
    var task_id = Number(td_obj.text())
    td_obj = td_obj.next().next()
    var project_name = td_obj.text()
    var task_des = td_obj.next().text()
    subcontent_show();

    show_task_report_info(task_id, project_name+":"+task_des);
  });
}

var report_timerid

var report_task_id = null
var report_task_info = null

var online_chart = null
var online_data = []
var online_index = 0
var online_option = null

var connect_chart = null
var connect_data = []
var connect_index = 0
var connect_option = null

var net_chart = null
var net_data = []
var net_index = 0
var net_option = null

var custom_chart = null
var custom_data = []
var custom_index = 0
var custom_option = null
var custom_xmax = 0

var api_data = []
var api_sort_index = null
var api_sort_ascending = true

var error_data = []
var error_index = 0

function show_task_report_info(task_id, task_des){
  $("#subdetail").html('<table width=100%>\
    <tr><td colspan=3><b>#'+task_id+':'+task_des+'</b></td></tr>\
    <tr><td colspan=3>&nbsp&nbsp&nbsp&nbsp<a id="report_case_info">用例步骤数:0&nbsp&nbsp&nbsp&nbsp用例时长:0时0分0秒</a>&nbsp&nbsp&nbsp&nbsp<a id="report_run_time_info">执行效率：</a>&nbsp&nbsp<font size="1">（*执行效率=用户运行时长/用例时长</font>）\
      <br>&nbsp&nbsp&nbsp&nbsp<a id="report_user_done_info">预计最大在线:0&nbsp&nbsp&nbsp&nbsp完成人数:0&nbsp;&nbsp;&nbsp;&nbsp;成功:0&nbsp&nbsp&nbsp&nbsp失败:0</a><br><br></td></tr>\
    <tr><td colspan=3><div id="online_chart" style="width:100%;height:250px;"></div></td></tr>\
    <tr><td colspan=3><div id="connect_chart" style="width:100%;height:250px;"></div></tr>\
    <tr><td colspan=3><div id="net_chart" style="width:100%;height:250px;"></div></tr>\
    <tr><td colspan=3><div id="custom_chart" style="width:100%;height:250px;"></div></td></tr>\
    <tr><td colspan=3><h3>&nbsp;接口统计</h3><div style="width:95%;margin-left:2%;overflow-y:scroll"><font size="1">(*点击表头排序)</font><table id="api_head" style="width:100%;table-layout:fixed"><thead>\
    <tr bgcolor="#aeeeee"><td rowspan=2 width=250>名称</td><td colspan=3>发送</td><td colspan=5>接收</td><td colspan=11>耗时(毫秒,百分位)</td></tr>\
    <tr bgcolor="#aeeeee"><td>次数(发)</td><td>流量(发)</td><td>平均(发)</td><td>次数(收)</td><td>流量(收)</td><td>平均(收)</td><td>正确</td><td>错误</td>\
    <td>10%</td><td>20%</td><td>30%</td><td>40%</td><td>50%</td><td>60%</td><td>70%</td><td>80%</td><td>90%</td><td>最小</td><td>最大</td></tr></thead></table></div>\
    <div style="width:95%;min-height:200px;max-height:800px;margin-left:2%;overflow-y:scroll"><table id="api_chart" style="width:100%;table-layout:fixed"></table></div></td></tr>\
    <tr><td colspan=3><h3>&nbsp;结果统计</h3><div style="width:95%;margin-left:2%"><table id="result_chart" width=100%></table></div>\
    <br><br><textarea id="error_chart" disabled rows="30" style="width:100%"></textarea></td></tr>\
    </table>');

  report_timerid = null

  report_task_id = task_id
  report_task_info = null

  online_chart = null
  online_data = []
  online_option = null
  online_index = 0

  connect_chart = null
  connect_data = []
  connect_index = 0
  connect_option = null

  net_chart = null
  net_data = []
  net_index = 0;
  net_option = null

  custom_chart = null
  custom_datat = []
  custom_index = 0
  custom_option = null
  custom_xmax = 0

  api_data = []
  api_sort_index = null
  api_sort_ascending = true

  error_data = []
  error_index = 0

  if (online_option == null){
    online_option = {title:{text:'人数统计'},grid:{left:'5%',right:'5%'},legend: {left:'10%',top:'0%'},dataZoom:[{type:"inside"}],tooltip:{trigger:'axis'},
    xAxis:{type:'category',boundaryGap:false,data:[]},yAxis: {nameTextStyle:{align:"left"},name: "单位:人"},
      series:[ {name:'总人数',type:'line',data:[]},{name:'启动',type:'line',data:[]},{name:'存活',type:'line',data:[]},
      {name:'在线',type:'line',data:[]},{name:'成功',type:'line',data:[]},{name:'错误',type:'line',data:[]}]
    }
  };
  online_chart = echarts.init(document.getElementById('online_chart'));
  online_chart.setOption(online_option);

  if (connect_option == null){
    connect_option = {title:{text:'连接统计'},grid:{left:'5%',right:'5%'},legend: {left:'10%',top:'0%'},dataZoom:[{type:"inside"}],tooltip:{trigger:'axis'},
    xAxis:{type:'category',boundaryGap:false},yAxis: {nameTextStyle:{align:"left"},name: "单位:个"},
      series:[]
    }
  };
  connect_chart = echarts.init(document.getElementById('connect_chart'));
  connect_chart.setOption(connect_option);

  if (net_option == null){
    net_option = {title:{text:'流量统计'},grid:{left:'5%',right:'5%'},legend: {left:'10%',top:'0%'},dataZoom:[{type:"inside"}],tooltip:{trigger:'axis', formatter:show_report_net_flow_formater},
    xAxis:{type:'category',boundaryGap:false},
    yAxis: {nameTextStyle:{align:"left"},name: "单位:字节/5秒  (*仅统计应用层流量，带宽数据为理论计算值)"},
      series:[]
    }
  };
  net_chart = echarts.init(document.getElementById('net_chart'));
  net_chart.setOption(net_option);

  if (custom_option == null){
    custom_option = {title:{text:'数量统计'},grid:{left:'5%',right:'5%'},legend: {left:'10%',top:'0%'},dataZoom:[{type:"inside"}],tooltip:{trigger:'axis'},xAxis:{type:'category',boundaryGap:false,data:[]},
    yAxis: {nameTextStyle:{align:"left"},name:"单位:无  (*自定义数量统计)"},
      series:[]
    }
  };
  custom_chart = echarts.init(document.getElementById('custom_chart'));
  custom_chart.setOption(custom_option);

  window.addEventListener("resize",function(){online_chart.resize();})
  window.addEventListener("resize",function(){connect_chart.resize();})
  window.addEventListener("resize",function(){net_chart.resize();})
  window.addEventListener("resize",function(){custom_chart.resize();})

  show_report_api_sort_select()
  show_report_chart_info(task_id)
  report_timerid = setInterval(function(){show_report_chart_info(task_id)}, 5000)
}

function show_report_net_flow_formater(parms){
  var len = parms.length
  var timestamp = ""
  var content = ""
  var item = null
  for (var i = 0;i<len;i++){
    item = parms[i]
    if (i == 0){
      timestamp = item.axisValue
    }
    var flow = Number(item.value[1])
    var Mb = (flow / (1024*1024)).toFixed(3)
    var Mbps = ((Number(item.value[2]) * 8) / (1024*1024*5)).toFixed(3)
    content += item.marker + item.seriesName + " " + item.value[1] + "字节(≈"+Mb+"Mb, 带宽：≈"+Mbps+"Mbps)"+ "<br>"
  }
  return timestamp + "<br>" + content
}

var case_time_length = 0
var chart_ref_count = 0
function show_report_chart_info(task_id){
  if ($("#subcontent").is(':hidden')) { clearInterval(report_timerid); return;};
  if (chart_ref_count > 0){return}
  http_post("/api/report_info", {"task_id":task_id},
    function(content){
      if (content.ret == "任务不存在"){clearInterval(report_timerid);return;}
      report_task_info = content.data
      chart_ref_count = 6
      case_time_length = report_task_info.case_time_len
      if (case_time_length == 0) case_time_length = 1
      var sec = case_time_length%60
      var min = Math.floor(case_time_length/60)
      var hou = Math.floor(min/60)
      min = min%60
      var info = '用例步骤:'+ report_task_info.case_step_len +'&nbsp&nbsp&nbsp&nbsp用例时长:'+hou+'时'+min+'分'+sec+'秒'
      $("#report_case_info").html(info)
      info = '预计最大在线人数:'+report_task_info.max_online+'&nbsp&nbsp&nbsp&nbsp完成人数:'+(report_task_info.run_success+report_task_info.run_failed) 
        +'&nbsp&nbsp&nbsp&nbsp成功:'+report_task_info.run_success+'&nbsp&nbsp&nbsp&nbsp失败:'+report_task_info.run_failed
      $("#report_user_done_info").html(info)
      show_report_online_chart_data(task_id, report_task_info.online.total);
      show_report_connect_chart_data(task_id, report_task_info.connect.total);
      show_report_net_chart_data(task_id, report_task_info.net.total);
      show_report_custom_chart_data(task_id, report_task_info.custom.total);
      show_report_error_chart_data(task_id, report_task_info.error.total);
      show_report_api_chart_data(task_id);
      if (report_task_info.state == 3 && report_task_info.online.total == online_index && report_task_info.error.total == error_index && 
        report_task_info.connect.total == connect_index && report_task_info.net.total == net_index){
          $("suboption").html('&nbsp&nbsp<bt id="report_data_download">导出数据</bt><bt id="report_html_download">导出报告</bt>')
          $("#report_data_download").click(show_report_data_download_chat_data)
          $("#report_html_download").click(show_report_html_download_chat_data)
          clearInterval(report_timerid)
          return
        }
    }
  );
}

function show_report_online_chart_data(task_id, size){
  if (online_index >= size){chart_ref_count--;return;}
  http_post("/api/report_online", {"task_id":task_id,"index":online_index,"count":10000},
    function(content){
      chart_ref_count--
      var data = content.data
      online_data.push(...data)
      online_index = online_index + data.length
      for (i = 0 ,len = data.length;i<len;i++){
        var item = data[i].split('|');
        x = timestampToTime(Number(item[0])*1000)
        online_option.xAxis.data.push(x)
        online_option.series[0].data.push(Number(item[1]))
        online_option.series[1].data.push(Number(item[2]))
        online_option.series[2].data.push(Number(item[3]))
        online_option.series[3].data.push(Number(item[4]))
        online_option.series[4].data.push(Number(item[5]))
        online_option.series[5].data.push(Number(item[6]))
      }
      online_chart.setOption(online_option);
    }
  );
}

function show_report_connect_chart_data(task_id, size){
  if (connect_index >= size){chart_ref_count--;return;}
  http_post("/api/report_connect", {"task_id":task_id,"index":connect_index,"count":10000},
    function(content){
      chart_ref_count--
      var data = content.data
      connect_data.push(...data)
      connect_index = connect_index + data.length
      for (i = 0 ,len = data.length;i<len;i++){
        var item = data[i].split('|');
        x = timestampToTime(Number(item[0])*1000)

        var exist = false
        for (j = 0, n = connect_option.series.length; j < n; j++){
          if (connect_option.series[j].key == item[1]){
            connect_option.series[j].data.push([x, item[2]]);
            connect_option.series[j+1].data.push([x, item[3]]);
            exist = true;
            break;
          }
        }
        if (exist == false){
          connect_option.series.push({key:item[1], name: item[1]+'成功', type:"line", data:[[x, item[2]]]})
          connect_option.series.push({key:item[1], name: item[1]+'失败', type:"line", data:[[x, item[3]]]})
        }
      }
      connect_chart.setOption(connect_option);
    }
  );
}

function show_report_net_chart_data(task_id, size){
  if (net_index >= size){chart_ref_count--;return;}
  http_post("/api/report_net", {"task_id":task_id,"index":net_index,"count":10000},
    function(content){
      chart_ref_count--
      var data = content.data
      net_data.push(...data)
      net_index = net_index + data.length
      for (i = 0 ,len = data.length;i<len;i++){
        var item = data[i].split('|');
        x = timestampToTime(Number(item[0])*1000)

        var exist = false
        for (j = 0, n = net_option.series.length; j < n; j++){
          if (net_option.series[j].key == item[1]){
            net_option.series[j].data.push([x, item[2], item[4]]);
            net_option.series[j+1].data.push([x, item[3], item[5]]);
            exist = true;
            break;
          }
        }
        if (exist == false){
          x0 = timestampToTime((Number(item[0]) - 5)*1000)
          net_option.series.push({key:item[1], name: item[1]+'上传', type:"line", data:[[x0, 0],[x, item[2], item[4]]]})
          net_option.series.push({key:item[1], name: item[1]+'下载', type:"line", data:[[x0, 0],[x, item[3], item[5]]]})
        }
      }
      net_chart.setOption(net_option);
    }
  );
}

function show_report_custom_chart_data(task_id, size){
  if (custom_index >= size){chart_ref_count--;return;}
  http_post("/api/report_custom", {"task_id":task_id,"index":custom_index,"count":10000}, 
    function(content){
      chart_ref_count--
      var data = content.data
      custom_data.push(...data)
      custom_index = custom_index + data.length
      for (i = 0 ,len = data.length;i<len;i++){
        var item = data[i].split('|');
        var timestamp = Number(item[0])
        if (custom_xmax == 0){
          custom_xmax = timestamp
          custom_option.xAxis.data.push(timestampToTime(timestamp*1000))
        }
        if (timestamp > custom_xmax){
          for (t = custom_xmax + 1; t <= timestamp; t++){
            custom_option.xAxis.data.push(timestampToTime(t*1000))
          }
          custom_xmax = timestamp
        }

        x = timestampToTime(timestamp*1000)
        var exist = false
        for (j = 0, n = custom_option.series.length; j < n; j++){
          if (custom_option.series[j].key == item[1]){
            custom_option.series[j].data.push([x, item[2]]);
            exist = true;
            break;
          }
        }
        if (exist == false){
          custom_option.series.push({key:item[1], name: item[1], type:"line", data:[[x, item[2]]]})
        }
      }
      custom_chart.setOption(custom_option);
    }
  );
}

var result_data = {}
var result_right = 0
var run_time_max = 0
var run_time_min = 0
var run_time_avg = 0
function show_report_error_chart_data(task_id, size){
  if (error_index >= size){chart_ref_count--;return;}
  http_post("/api/report_error", {"task_id":task_id,"index":error_index,"count":10000},
    function(content){
      chart_ref_count--
      var data = content.data
      error_data.push(...data)
      error_index = error_index + data.length
      var temptext = ""
      for (i = 0 ,len = data.length;i<len;i++){
        var item = data[i].split('|');
        item[0] = timestampToTime(Number(item[0])*1000)
        temptext = temptext + item.toString() + "\n"
        //set result_chart
        reason = item[6]
        if (reason == "结束原因:"){
          result_right = result_right + 1
          var run_time_length = item[4].replace("运行时长:", "").replace("秒", "")
          if (run_time_length == 0) run_time_length = 1
          if (run_time_length > run_time_max) { run_time_max = run_time_length }
          if (run_time_length < run_time_min || run_time_min == 0 ){ run_time_min = run_time_length }
          run_time_avg = (run_time_length - run_time_avg) / result_right + run_time_avg
        }
        else{
          reason = reason.replace("结束原因:", "")
          if (result_data[reason] == null){
            result_data[reason] = 1
          }
          else{
            result_data[reason] = result_data[reason] + 1
          }
        }
      }
      $("#error_chart").append(temptext)
      var max = (run_time_max / case_time_length).toFixed(2)
      var min = (run_time_min / case_time_length).toFixed(2)
      var avg = (run_time_avg / case_time_length).toFixed(2)
      $("#report_run_time_info").html("执行效率：最大["+max+"]&nbsp&nbsp最小["+min+"]&nbsp&nbsp平均["+avg+"]")
      var result_str = '<tr bgcolor=\"#aeeeee\"><td width=500>正确</td><td>'+result_right+'</td></tr>'
      var i = 0
      for (var err_str in result_data){
        var touming = 1
        if ((i % 2) != 0){
          touming = 0.7
        }
        i = i + 1
        result_str += '<tr style="background-color:rgba(96, 205, 205, '+ touming +')"><td width=500>'+ err_str+'</td><td>'+result_data[err_str]+'</td></tr>'
      }
      $("#result_chart").html(result_str)
    }
  );
}

function show_report_api_sort_select(){
  $("#api_head td").click(function () {
    var name = $(this).text()
    if (name == api_sort_index){
      api_sort_ascending = api_sort_ascending ? false : true
    } 
    else if(name != "耗时(毫秒,百分位)" && name != "发送" && name != "接收"){
      api_sort_index = name
      api_sort_ascending = false
    }
    show_report_api_chart_data_content(api_data)
  });
}

function show_report_api_chart_data(task_id){
  http_post("/api/report_api", {"task_id":task_id},
  function(content){
      chart_ref_count--
      var data = content.data
      api_data = data
      show_report_api_chart_data_content(data)
    }
  );
}

function show_report_api_chart_data_sort(data){
  if (api_sort_index == "名称"){data.sort(function(a, b){return api_sort_ascending? b.api.localeCompare(a.api) : a.api.localeCompare(b.api)})}
  else if (api_sort_index == "次数(发)"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a.send_count, b.send_count)})}
  else if (api_sort_index == "流量(发)"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a.send_flow, b.send_flow)})}
  else if (api_sort_index == "平均(发)"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a.send_count?a.send_flow/a.send_count:null, b.send_count?b.send_flow/b.send_count:null)})}
  else if (api_sort_index == "次数(收)"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a.recv_count, b.recv_count)})}
  else if (api_sort_index == "流量(收)"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a.recv_flow, b.recv_flow)})}
  else if (api_sort_index == "平均(收)"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a.recv_count?a.recv_flow/a.recv_count:null, b.recv_count?b.recv_flow/b.recv_count:null)})}
  else if (api_sort_index == "正确"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a.success, b.success)})}
  else if (api_sort_index == "错误"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a.error, b.error)})}
  else if (api_sort_index == "最小"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a.min, b.min)})}
  else if (api_sort_index == "最大"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a.max, b.max)})}
  else if (api_sort_index == "10%"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a["10"], b["10"])})}
  else if (api_sort_index == "20%"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a["20"], b["20"])})}
  else if (api_sort_index == "30%"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a["30"], b["30"])})}
  else if (api_sort_index == "40%"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a["40"], b["40"])})}
  else if (api_sort_index == "50%"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a["50"], b["50"])})}
  else if (api_sort_index == "60%"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a["60"], b["60"])})}
  else if (api_sort_index == "70%"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a["70"], b["70"])})}
  else if (api_sort_index == "80%"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a["80"], b["80"])})}
  else if (api_sort_index == "90%"){data.sort(function(a, b){return show_report_api_chart_data_sort_value(a["90"], b["90"])})}
}

function show_report_api_chart_data_sort_value(a, b){
    if (a == null && b == null) return 0
    else if(a == null && b != null){return 1}
    else if(a != null && b == null){return -1}
    else{ return api_sort_ascending? a - b : b - a}
}

function flow_format(value){
  var fixstr = ["B","K","M","G","T"]
  var i = 0
  while(true){
    if (value < 1024){break}
    value = value/1024
    i++
  }
  return value.toFixed(i>2?2:0) + fixstr[i]
}

function show_report_api_chart_data_content(data){
  show_report_api_chart_data_sort(data)
  var temptext = ""
  for (i = 0 ,len = data.length;i<len;i++){
    var item = data[i]
    var touming = 1
    if ((i % 2) != 0){
      touming = 0.7
    }
    item_send_flow = item.send_flow != null?flow_format(item.send_flow) : "-"
    item_send_count = item.send_count != null?item.send_count : "-"
    item_send_avg_title = item.send_count == null ? null: (item.send_flow/item.send_count).toFixed(0)
    item_send_avg = item_send_avg_title == null ? "-" : flow_format(Number(item_send_avg_title))
    item_recv_flow = item.recv_flow != null?flow_format(item.recv_flow) : "-"
    item_recv_count = item.recv_count != null?item.recv_count : "-"
    item_recv_avg_title = item.recv_count== null?null:(item.recv_flow/item.recv_count).toFixed(0)
    item_recv_avg = item_recv_avg_title== null?"-":flow_format(Number(item_recv_avg_title))
    item_success = item.success != null?item.success:"-"
    item_error = item.error != null?item.error:"-"
    item_min = item.min != null?item.min : "-"
    item_max = item.max != null?item.max : "-"
    item_10 = item["10"]!= null?item ["10"]:"-"
    item_20 = item["20"]!= null?item ["20"]:"-"
    item_30 = item["30"]!= null?item ["30"]:"-"
    item_40 = item["40"]!= null?item ["40"]:"-"
    item_50 = item["50"]!= null?item ["50"]:"-"
    item_60 = item["60"]!= null?item ["60"]:"-"
    item_70 = item["70"]!= null?item ["70"]:"-"
    item_80 = item["80"]!= null?item ["80"]:"-"
    item_90 = item["90"]!= null?item ["90"]:"-"
    rowtext = '<tr><td width=250 title="'+item.api+'" style="background-color:rgba(96, 205, 205, '+ touming +');overflow:hidden;text-overflow:ellipsis;">'+item.api+'</td>\
    <td style="background-color:rgba(188, 210, 238, '+ touming +')">'+item_send_count+'</td>\
    <td style="background-color:rgba(188, 210, 238, '+ touming +')"'+ (item.send_flow?' title="'+item.send_flow+'字节"':"")+'>'+item_send_flow+'</td>\
    <td style="background-color:rgba(188, 210, 238, '+ touming +')"'+ (item_send_avg_title?' title="'+item_send_avg_title+'字节"':"")+'>'+item_send_avg+'</td>\
    <td style="background-color:rgba(188, 210, 238, '+ touming +')">'+item_recv_count+'</td>\
    <td style="background-color:rgba(188, 210, 238, '+ touming +')"'+ (item.recv_flow?' title="'+item.recv_flow+'字节"':"")+'>'+item_recv_flow+'</td>\
    <td style="background-color:rgba(188, 210, 238, '+ touming +')"'+ (item_recv_avg_title?' title="'+item_recv_avg_title+'字节"':"")+'>'+item_recv_avg+'</td>\
    <td style="background-color:rgba(188, 210, 238, '+ touming +')">'+item_success+'</td><td style="background-color:rgba(188, 210, 238, '+ touming +')">'+item_error+'</td>\
    <td style="background-color:rgba(178, 223, 238, '+ touming +')">'+item_10+'</td><td style="background-color:rgba(178, 223, 238, '+ touming +')">'+item_20+'</td>\
    <td style="background-color:rgba(178, 223, 238, '+ touming +')">'+item_30+'</td><td style="background-color:rgba(178, 223, 238, '+ touming +')">'+item_40+'</td>\
    <td style="background-color:rgba(178, 223, 238, '+ touming +')">'+item_50+'</td><td style="background-color:rgba(178, 223, 238, '+ touming +')">'+item_60+'</td>\
    <td style="background-color:rgba(178, 223, 238, '+ touming +')">'+item_70+'</td><td style="background-color:rgba(178, 223, 238, '+ touming +')">'+item_80+'</td>\
    <td style="background-color:rgba(255, 180, 180, '+ touming +')">'+item_90+'</td><td style="background-color:rgba(242, 223, 238, '+ touming +')">'+item_min+'</td>\
    <td style="background-color:rgba(242, 223, 238, '+ touming +')">'+item_max+'</td>\</tr>'
    temptext = temptext + rowtext
  }
  $("#api_chart").html(temptext)
}

function show_report_data_download_chat_data(){
  var task = task_list_data[report_task_id]
  var report_download_data = {"task_info":task,"report_info":report_task_info, "online":online_data, 
    "connect":connect_data, "net":net_data, "custome":custom_data,
    "api":api_data, "error":error_data}
  var file_name = timestampToTime(report_task_info.start_time*1000) + "_"+ task.project_name + "_" + task.des
  file_name = file_name.replace(" ", "_")

  var alink = document.createElement('a')
  alink.href = "data:text/plain;charset=utf-8," + encodeURIComponent(JSON.stringify(report_download_data, null, '\t'))
  alink.download = file_name+".txt"
  alink.click()
}

function show_report_html_download_chat_data(){
  var task = task_list_data[report_task_id]
  var report_download_data = {"task_info":task,"report_info":report_task_info, "online":online_data, 
    "connect":connect_data, "net":net_data, "custome":custom_data,
    "api":api_data, "error":error_data}
  var sorce_data = JSON.stringify(report_download_data)
  var report_page = ReportTemplate.replace("report_sorce_data", sorce_data)
  var file_name = timestampToTime(report_task_info.start_time*1000) + "_"+ task.project_name + "_" + task.des
  file_name = file_name.replace(" ", "_")
  var alink = document.createElement('a')
  alink.href = "data:text/plain;charset=utf-8," + encodeURIComponent(report_page)
  alink.download = file_name + ".html"
  alink.click()
}

function click_nav_case(){
  $("bhead").append('\
  此处管理控制端用例录制功能开启或关闭；并且提供简单的用例降噪功能。</br></br>\
  <bt id="case_record" onclick="javascript:show_case_record();">录制用例</bt> | \
  <bt id="case_http" onclick="javascript:show_case_http();">http用例</bt><br>\
  <div id="div_case_doc"></div>');
  var sub = QueryParms.case
  if (sub == "record"){
    show_case_record()
  }
  else if (sub == "http"){
    show_case_http()
  }
  else{
    show_case_record()
  }
}

function show_case_record(){
  QueryParms.case='record'
  history.replaceState(null, "",'?project='+ QueryParms.project + '&nav=' + QueryParms.nav + '&case=' + QueryParms.case);
  var doc = '<font color="#009999">[录制用例]</font></br>录制:&nbsp;&nbsp;<bt id="record_flag">开启</bt>(剩余：<a id="record_left">0</a>)</br>\
  项目：<select id="project" class="project_select" disabled></select></br>\
  备注：<input id="des" type="text"></br>\
  <table id="record_def"></table><bt id="record_def_delete">删除</bt>&nbsp&nbsp&nbsp&nbsp<bt id="record_save">保存</bt>'
  $("#div_case_doc").html(doc)

  $("#project").append(show_project_select());
  show_record_flag({});
  show_record_default();
  show_case_list_flush()

  $("#record_flag").click(function(){
    var flag = false;
    if ($("#record_flag").text() == "开启"){
      flag = true;
    }
    show_record_flag({"record":flag});
  });
  $("#record_def_delete").click(function(){
    var jsondata = {"case_dir":QueryParms.case,"case_file":"default.db", "addr":[]};
    $(".checkdef"+":checked").each(function(index, item){
      jsondata.addr.push($(this).val());
      $(this).parent().remove();
    });
    http_post("/api/case_addr_delete", jsondata, null)
  })
  $("#record_save").click(function(){
    var des = $("#des").val();
    var projectid = Number($("#project").val());
    http_post("/api/case_save", {"case_dir":QueryParms.case,"project_id":projectid, "des":des},
      function(content){
        show_record_default();
        show_case_list_flush();
      }
    );
  })

  function show_record_flag(jsondata){
    http_post("/api/case_record", jsondata,
      function(content){
        if (content.record == true){
          $("#record_flag").text("关闭");
        }
        else{
          $("#record_flag").text("开启");
        }
        $("#record_left").text(content.left);
      }
    );
  }
}

function show_record_default(){
  http_post("/api/case_addr_list", {"case_dir":QueryParms.case, "case_file":"default.db"}, 
    function(content){
      var array = content.data.record_list;
      if (array.length == 0){
        return;
      }
      var text = ""
      for (i = 0; i < array.length; i++){
        var item = array[i];
        text += '<tr><td><input class="checkdef"'+' type="checkbox" value="'+item.addr+'">'+item.addr+'</td></tr>'
      }
      $("#record_def").html(text)
    }
  );
}

function show_case_list_flush(){
  http_post("/api/case_list", {"case_dir":QueryParms.case}, 
    function show_record_list(content){
      var row = "<thead><tr><td>编号</td><td>说明</td><td>项目</td><td>用例名</td><td>记录端口</td><td>操作</td></tr></thead>";
      var array = content.data;
      for (var i = 0; i < array.length; i++){
        var item = array[i];
        if (item.case_file == "default.db") {continue}
        row += '<tr valign=top>\
        <td>' + i +'</td>\
        <td class="record_des" width=300><a>'+ item.des +'</a><input type=text value="'+item.des+'" hidden></td>\
        <td width=200><a>'+ item.project +'</a><select hidden>'+show_project_select(item.project)+'</select></td>\
        <td width=250><bt class="db_name">'+ item.case_file +'</bt></td>\
        <td width=300><bt class="record_port">展开</bt>&nbsp;&nbsp;&nbsp;&nbsp;\
          <bt class="table_delete" hidden>删除选定</bt></br>\
          <table></table></td>\
        <td><bt class="case_info_edit">编辑</bt><bt class="case_info_commit" hidden>确定</bt>\
        <bt class="case_info_cancel" hidden>取消</bt><bt class="case_delete">删除</bt>' + case_edit_doc() + '</td></tr>'
      }
      $("#list").html(row);

      $(".case_info_edit").click(function(){
        $(this).hide()
        $(this).next().show()
        $(this).next().next().show()
        $(this).next().next().next().hide()

        var porject_obj =  $(this).parent().prev().prev().prev()
        var des_obj = porject_obj.prev()
        porject_obj.find("a").hide()
        porject_obj.find("select").show()
        des_obj.find("a").hide()
        des_obj.find("input").show()
      })

      $(".case_info_cancel").click(function(){
        $(this).hide()
        $(this).prev().hide()
        $(this).prev().prev().show()
        $(this).next().show()

        var porject_obj =  $(this).parent().prev().prev().prev()
        var des_obj = porject_obj.prev()
        porject_obj.find("a").show()
        porject_obj.find("select").hide()
        des_obj.find("a").show()
        des_obj.find("input").hide()
      })

      $(".case_info_commit").click(function(){
        $(this).hide()
        $(this).prev().show()
        $(this).next().next().show()
        $(this).next().hide()

        var porject_obj =  $(this).parent().prev().prev().prev()
        var des_obj = porject_obj.prev()
        var project_id = Number(porject_obj.find("select").val())
        var project_name = porject_obj.find("select").find("option:selected").text()
        var project_des = des_obj.find("input").val()

        porject_obj.find("a").text(project_name)
        porject_obj.find("a").show()
        porject_obj.find("select").hide()
        des_obj.find("a").text(project_des)
        des_obj.find("a").show()
        des_obj.find("input").hide()

        var case_file = $(this).parent().prev().prev().text()
        http_post("/api/case_info_update", {"case_dir":QueryParms.case, "case_file": case_file, "des":project_des, "project_id":project_id})
      })

      $(".case_delete").click(function(){
        var tr_obj = $(this).parent().parent()
        var des_obj = tr_obj.find("td:first").next()
        var des = des_obj.text()
        var project_name = des_obj.next().find("a:first").text()
        var case_file = des_obj.next().next().text()
    
        var flag = confirm('删除用例:'+case_file+'\n'+project_name+':'+des+'\n\n是否继续？')
        if (flag){
          tr_obj.remove()
          var jsondata = {"case_dir":QueryParms.case, "case_file":case_file};
          http_post("/api/case_delete", jsondata, show_case_list_flush)
          if (QueryParms.case == "http"){
            http_post("/api/case_json", {"case_dir":QueryParms.case, "case_file":case_file,"opcode":2})
          }
        }
      });

      $(".table_delete").click(function(){
        var obj = $(this).next().next().next();
        var trSeq = $(this).parent().parent().parent().find("tr").index($(this).parent().parent());
        var case_file = $("#list tr:gt(0):eq("+trSeq+") td:eq(3)").text();
    
        var jsondata = {"case_dir":QueryParms.case, "case_file":case_file, "addr":[]};
        $(".check_"+trSeq+":checked").each(function(index, item){
          jsondata.addr.push($(this).val());
          $(this).parent().remove();
        });
        http_post("/api/case_addr_delete", jsondata, null)
      });

      $(".record_port").click(function(){
        var obj = $(this).next().next().next();
        if ($(this).text() == "收拢"){
          $(this).text("展开");
          $(this).next().hide();
          obj.empty()
          return;
        }
        $(this).next().show();
        var trSeq = $(this).parent().parent().parent().find("tr").index($(this).parent().parent());
        $(this).text("收拢");
        var case_file = $("#list tr:gt(0):eq("+trSeq+") td:eq(3)").text();
        var jsondata = {"case_dir":QueryParms.case, "case_file":case_file};
        http_post("/api/case_addr_list", jsondata,
          function(content){
            var array = content.data.record_list;
            var text = ""
            for (i = 0; i < array.length; i++){
            var item = array[i];
            text += '<tr><td><input class="check_'+trSeq+'" type="checkbox" value="'+item.addr+'">'+item.addr+'</td></tr>'
            }
            obj.html(text)
          }
        );
      });

      $(".db_name").click(function () {
        subcontent_show();
        var dbname = $(this).text()
        var des = $(this).parent().prev().prev().children((":first")).text()
        var doc = '#用例：<b>'+ des + '[' + dbname + ']' + '</b></br>\
          <table id="case_view" style="width:100%;font-size:13;">\
          <thead><tr><td width=40>序号</td><td width=60>事件(id)</td><td width=60>连接</td><td width=150>时间(微秒)</td>\
          <td width=150>地址</td><td>消息(base64)</td><td>解码（<bt id="plaintext">明文</bt> | <bt id="ciphertext">HEX</bt>）</td></tr></thead></table>'
        $("#subdetail").html(doc)
        var jsondata = {"case_dir": QueryParms.case, "case_file": dbname, "index":0, "count":10000}
        http_post("/api/case_view", jsondata, 
          function(content){
            var array = content.data;
            if (array.length == 0){
              return;
            }
            var temptext = ""
            for (i = 0; i < array.length; i++){
              var item = array[i].split("|");
              var event = item[1] == "1"? "发送": (item[1] == "0"?"连接":"关闭")
              var conn_type_def = {"0":"TCP", "1":"UDP", "2":"SSL", "8":"HTTP", "9":"HTTPS"}
              var conn_type = conn_type_def[item[2]]
              var src_text = window.atob(item[4])
              var hex_text = strt_to_hex(src_text)
              var src_text = src_text.replace(/\r/g, "\\r")
              var src_text = src_text.replace(/\n/g, "\\n")
              temptext = temptext + '<tr><td><pre>'+i+'</pre></td>\
              <td><pre>'+event+'('+item[1]+')'+'</pre></td>\
              <td><pre>'+conn_type+'('+item[2]+')'+'</pre></td>\
              <td><pre>'+item[0]+'</pre></td><td><pre>'+item[3]+'</pre></td><td style="width:200"><pre><input type=text value='+item[4]+' disabled></pre></td>\
              <td><pre class="src_plaintext">'+src_text+'</pre><pre class="hex_ciphertext" hidden>'+hex_text+'</pre></td></tr>'
            }
            $("#case_view").append(temptext);
          }
        );

        $("#plaintext").click(function(){
          $(".src_plaintext").show()
          $(".hex_ciphertext").hide()
        });

        $("#ciphertext").click(function(){
          $(".src_plaintext").hide()
          $(".hex_ciphertext").show()
        });
      });  
      
      function case_edit_doc(){
        if (QueryParms.case == "record"){ return ""}
        else{
          return '<bt class="case_edit">编辑用例</bt>'
        }
      }

      $(".case_edit").click(function(){
        var trSeq = $(this).parent().parent().parent().find("tr").index($(this).parent().parent());
        var case_file = $("#list tr:gt(0):eq("+trSeq+") td:eq(3)").text();
        var des = $("#list tr:gt(0):eq("+trSeq+") td:eq(1)").text();
        show_case_http_edite(case_file, des)
      })
    }
  );
}

function strt_to_hex(str){
  var hex_code = []
  var chars = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"]
  for (var i = 0; i < str.length;i++){
    var char_code = str[i].charCodeAt()
    var bit = char_code >> 4
    hex_code.push(chars[bit])
    bit = char_code &0x0f
    hex_code.push(chars[bit])
    hex_code.push(" ")
    if (i % 32 == 31){
      hex_code.push("\n")
    }
    else if (i % 8 == 7){
      hex_code.push("| ")
    }
  }
  return hex_code.join("")
}

function show_case_http(){
  QueryParms.case='http'
  history.replaceState(null, "",'?project='+ QueryParms.project + '&nav=' + QueryParms.nav + '&case=' + QueryParms.case);
  var doc = '<font color="#009999">[http用例]</font></br><font><bt id="create_http_case">1.创建http用例</bt></font>'
  $("#div_case_doc").html(doc)
  show_case_list_flush()

  $("#create_http_case").click(function(){
    show_case_http_edite(null, "")
  });
}

function show_case_http_edite(case_file, des){
  subcontent_show();
  var case_content = []
  KeydownCallback = function(e){
    if (e.key == "F5"){
      var flag = confirm("您正在刷新页面，未保存的数据将会丢失，是否继续？")
      return flag
    }
  }

  $("suboption").append('&nbsp;&nbsp;<bt id="http_case_clean">清空用例步骤</bt>')
  $("#subdetail").html('\
    项目：<select id="http_case_project" class="project_select" disabled></select>&nbsp;\
    用例名：<input id="http_case_file" type="text" value="'+ (case_file?case_file:'') +'" disabled>\
    说明：<input id="http_case_des" type="text" value="' + des + '" placeholder="填写说明信息">&nbsp;&nbsp;<bt id="http_case_save">保存</bt>'+'&nbsp;<bt id="http_case_save_as"'+(case_file?'':' hidden')+'>另存</bt>'+'\
    <table width=100%><tr>\
      <td style="width:30%;vertical-align:top">\
        <div style="width:100%;overflow-y:scroll"><table style="width:100%;table-layout:fixed"><thead>\
        <tr bgcolor="#aeeeee\"><td width=100px>操作</td><td width=100px>步骤</td><td width=150px>说明</td><td width=100px>间隔(ms)</td><td width=100px>方法</td><td>URL</td></tr></thead></table></div>\
        <div id="div_http_case_list" style="width:100%;overflow-y:scroll;max-height:70vh">\
          <table id="http_case_list" style="width:100%;max-height:500;table-layout:fixed"></table>\
        </div>\
        <div style="width:100%;overflow-y:scroll">\
          <table width=100%>\
            <tr style="background-color:rgba(96, 205, 205, 1)"><td width=100px>*</td><td width=100px>*</td>\
            <td width=150px><input id="http_des" type="text" placeholder="步骤说明" style="width:150px"></td>\
            <td width=100px><input id="http_space_time" type="text" style="width:80px" value=10></td>\
            <td width=100px>\
              <select id="http_method">\
                <option value ="GET">GET</option>\
                <option value ="POST">POST</option>\
                <option value ="PUT">PUT</option>\
                <option value ="HEAD">HEAD</option>\
              </select>\
            </td><td>\
              <input id="http_url" type="text" placeholder="http://localhost:1080/" style="width:480px">&nbsp;<bt id="http_case_push">添加</bt>\
              <bt id="http_case_insert">插入</bt>\
            </td>\
            </tr>\
          </table>\
       </div>\
      </td>\
    </tr></table>');
  $("#http_case_project").append(show_project_select())

  if (case_file){
    http_post("/api/case_json", {"case_dir":QueryParms.case, "case_file":case_file, "opcode":1}, 
      function(response){
        if (response.ret_code != 0){ return }
        case_content = response.data
        var doc = ''
        for (var i = 0; i < case_content.length; i++){
          var item = case_content[i]
          var flag = i % 2 
          if (flag == 0){
            flag = 1
          }
          else{
            flag = 0.7
          }
          var method = item.method
          var http_url = item.url
          doc += '<tr style="background-color:rgba(96, 205, 205, '+ flag +')">\
          <td width=100px><bt class="http_case_mod">编辑</bt>&nbsp;<bt class="http_case_del">删除</bt>&nbsp;\
          </td><td width=100px>'+i+'</td><td width=150px>'+item.des+'</td><td width=100px>'+item.space_time+'</td><td width=100px>'+method+'</td><td>'+http_url+'</td></tr>'
        }
        $("#http_case_list").html(doc)
        http_case_step_click() 
      }
    );
  }

  function http_case_step_click(){
    $(".http_case_del").unbind('click')
    $(".http_case_del").click(function(){
      var td_obj = $(this).parent()
      var tr_obj = td_obj.parent()
      var trSeq = Number(td_obj.next().text())

      for (var i = trSeq;tr_obj = tr_obj.next(), tr_obj.length != 0; i++){
        tr_obj.children(":first").next().text(i)
      }
      
      $("#http_case_list tr").eq(trSeq).remove()
      case_content.splice(trSeq, 1)
    });

    $(".http_case_mod").unbind('click')
    $(".http_case_mod").click(function(){
      var tr_obj = $(this).parent().parent()
      var step_number = Number($(this).parent().next().text())
      var item = case_content[step_number]

      $("float_window").show()
      $("#float_content").html('<br><table width=100%>\
        <tr><td width=60>步骤：</td><td>'+step_number+'</td></tr>\
        <tr><td>说明：</td><td><input id="http_des_mod" type="text" placeholder="步骤说明" style="width:150px"></td></tr>\
        <tr><td>间隔：</td><td><input id="http_space_time_mod" type="text" style="width:80px">毫秒</td></tr>\
        <tr valign="top"><td>方法:</td><td><select id="http_method_mod"><option value ="GET">GET</option>\
          <option value ="POST">POST</option>\
          <option value ="PUT">PUT</option>\
          <option value ="HEAD">HEAD</option>\
        </select></td></tr>\
        <tr valign="top"><td>URL：</td><td><input id="http_url_mod" type="text" placeholder="http://localhost:1080/" style="width:100%"></td></tr>\
        <tr valign="top"><td>Query：</td><td><input id="http_query_mod" type="text" style="width:100%"></td></tr>\
        <tr valign="top"><td>Header：</td><td>\
        <textarea id="http_head_mod" rows=10 style="width:100%;resize:none;"></textarea></td></tr>\
        <tr valign="top"><td>Content: </td><td><textarea id="http_content_mod" rows=10 style="width:100%;resize:none;"></textarea></td></tr>\
        <tr><td></td><td><br><bt id="http_case_mod_submit">确认修改</bt></td></tr>\
        </table>')
      $("#http_des_mod").val(item.des)
      $("#http_space_time_mod").val(item.space_time)
      $("#http_method_mod").val(item.method)
      $("#http_url_mod").val(item.url)
      $("#http_query_mod").val(item.query)
      $("#http_head_mod").val( JSON.stringify(item.header))
      $("#http_content_mod").val(item.content)

      
      $("#http_case_mod_submit").click(function(){
        var des = $("#http_des_mod").val()
        var space_time = $("#http_space_time_mod").val()
        var method = $("#http_method_mod").val()
        var url = $("#http_url_mod").val()
        var query = $("#http_query_mod").val()
        var header = JSON.parse($("#http_head_mod").val())
        var content = $("#http_content_mod").val()
        if (step_number < case_content.length){
          case_content[step_number] = {"des":des,"space_time":space_time,"method":method, "url":url, "query":query, "header":header, "content":content}
          var td_obj = tr_obj.children(":first").next().next()
          td_obj.text(des)
          td_obj.next().text(space_time)
          td_obj.next().next().text(method)
          td_obj.next().next().next().text(url)
        }
      })
    });
  }

  $("#http_case_clean").click(function(){
    $("#http_case_list").empty()
    case_content = []
  });

  $("#http_case_save").click(function(){
    var case_file = $("#http_case_file").val()
    var project_id = Number($("#http_case_project").val())
    var des = $("#http_case_des").val()
    jsondata = {"case_dir":QueryParms.case, "project_id":project_id, "des": des}
    if (case_file.length > 0){
      jsondata["case_file"] = case_file
      var flag = confirm("即将覆盖用例:"+ case_file +"，此过程需要较长时间，请耐心等待！\n是否继续？")
      if(!flag) return
    }
    else{
      var flag = confirm("即将存储新用例，此过程需要较长时间，请耐心等待！\n是否继续？")
      if(!flag) return
    }
    
    http_case_save_create(jsondata)
  });

  $("#http_case_save_as").click(function(){
    var project_id = Number($("#http_case_project").val())
    var des = $("#http_case_des").val()
    jsondata = {"case_dir":QueryParms.case, "project_id":project_id, "des": des}
    var flag = confirm("即将存储新用例，此过程需要较长时间，请耐心等待！\n是否继续？")
      if(!flag) return
    http_case_save_create(jsondata)
  });

  function http_case_save_create(jsondata){
    http_post("/api/case_create", jsondata, 
      function(response){
        if (case_content.length > 0){
          http_case_step_encode(response.case_file, 0, 0)
        }
        else{
          show_case_http_save_json(case_file)
          // alert("成功导入用例["+response.case_file+"],步骤数：0")
        }
      }
    );
  }

  function http_case_step_encode(case_file, case_index, start_time){
    var step = case_content[case_index]
    start_time += Number(step.space_time)
    var protocol = 8, host = "", port = 80, uri = ""
    var url = step.url
    if ("http://" == url.slice(0, 7)){ url=url.slice(7, url.length)}
    else if("https://" == url.slice(0, 8)){protocol = 9, port = 443, url=url.slice(8, url.length)}
    var index = url.indexOf('/')
    if (index < 0) {
      uri = "/"
      host = url
    }else{
      uri = url.slice(index, url.length)
      host = url.slice(0, index)
    }
    index = host.indexOf(':')
    if (index >= 0){port = Number(host.substring(index + 1)), host = host.slice(0, index)}

    if (step.query != ""){uri += "?"+ step.query}
    var stream = step.method + " " + uri + " HTTP/1.1\r\n"
    var header = step.header
    if (step.content.length > 0){
      header["Content-Length"] = step.content.length
    }
    for (let k in header){
      stream += k + ": " + header[k] + "\r\n"
    }
    stream += "\r\n" + step.content
    var jsondata = {"case_dir":QueryParms.case, "case_file":case_file, "recordtime":String(start_time*1000), "event_type":1, "protocol":protocol, "host":host, "port":port, "sessionid":0, "content":stream, "note":step.des}
    http_post("/api/case_append", jsondata, 
      function(){
        if (case_content.length > case_index + 1){
          http_case_step_encode(case_file, case_index + 1, start_time)
        }
        else{
          show_case_http_save_json(case_file)
          // alert("成功导入用例["+case_file+"],步骤数:"+case_content.length)
        }
      }
    );
  }

  function show_case_http_save_json(case_file){
    http_post("/api/case_json", {"case_dir":QueryParms.case, "case_file":case_file, "opcode":0, "data": case_content}, 
      function(response){
        $("#http_case_file").val(case_file)
        $("#http_case_save_as").show()
        alert("成功导入用例["+case_file+"],步骤数:"+case_content.length)
      }
    )
    show_case_list_flush()
  }

  $("#http_case_push").click(function(){
    var http_des = $("#http_des").val()
    var space_time = $("#http_space_time").val()
    var method = $("#http_method").val()
    var http_url = $("#http_url").val()
    var case_index = case_content.length
    var flag = case_index % 2 
    if (flag == 0){
      flag = 1
    }
    else{
      flag = 0.7
    }
    $("#http_case_list").append('<tr style="background-color:rgba(96, 205, 205, '+ flag +')">\
    <td width=100px><bt class="http_case_mod">编辑</bt>&nbsp;<bt class="http_case_del">删除</bt>&nbsp;</td>\
    <td width=100px>'+case_index+'</td><td width=150px>'+http_des+'</td><td width=100px>'+space_time+'</td><td width=100px>'+method+'</td><td>'+http_url+'</td></tr>')
    var step = {"des":http_des,"space_time":space_time,"method":method, "url":http_url, "content":"", "query":"", "header":{}}
    case_content.push(step)
    $('#div_http_case_list').scrollTop($('#div_http_case_list')[0].scrollHeight);

    http_case_step_click()
  });

  $("#http_case_insert").click(function(){
    var http_des = $("#http_des").val()
    var space_time = $("#http_space_time").val()
    var method = $("#http_method").val()
    var http_url = $("#http_url").val()
    var case_index = case_content.length
    var flag = case_index % 2 
    if (flag == 0){
      flag = 1
    }
    else{
      flag = 0.7
    }
    var pos = prompt("请输入插入位置：")
    if (pos == null || Number(pos) == NaN || Number(pos) < 0){
      return
    }
    pos = Number(pos)
    var step = {"des":http_des,"space_time":space_time,"method":method, "url":http_url, "content":"", "query":"", "header":{}}
    case_content.splice(pos, 0, step)

    var html_doc = ""
    for (var i = 0; i < case_content.length; i++){
      var item = case_content[i]
      var flag = i % 2 
      if (flag == 0){
        flag = 1
      }
      else{
        flag = 0.7
      }
      var method = item.method
      var http_url = item.url
      html_doc += '<tr style="background-color:rgba(96, 205, 205, '+ flag +')">\
      <td width=100px><bt class="http_case_mod">编辑</bt>&nbsp;<bt class="http_case_del">删除</bt>&nbsp;\
      </td><td width=100px>'+i+'</td><td width=150px>'+item.des+'</td><td width=100px>'+item.space_time+'</td><td width=100px>'+method+'</td><td>'+http_url+'</td></tr>'
    }
    $("#http_case_list").html(html_doc)

    http_case_step_click()
  })
}

function click_nav_report(){
  $("bhead").append("此处显示压测测试报告，存储测试报告的功能由控制端lua扩展实现");
  $.ajax({ type: "get", url: website_host() + "/report", success: function(data){ 
    $("#list").append(data)
  }});
}

function click_nav_proxy(){
  $("bhead").append("此处显示当前代理服务器代理的连接列表，支持http、https、socks5代理，代理服务端口号默认为1080");
  http_post("/api/proxy_list", {},
    function show_proxy_list(content){
      var head = "<thead><tr><td>编号</td><td>地址</td></tr></thead>";
      $("#list").append(head);
      var array = content.data;
      if (array.length == 0){
        return;
      }
      for (i = 0; i < array.length; i++){
        var item = array[i];
        var row = "<tr id=\"list"+ i + "\"><td>"+i+"</td><td>"+ item.addr +"</td></tr>"
        $("#list").append(row);
      }
    }
  )
}

function click_nav_agent(){
  $("bhead").append("此处显示当前负载端列表，控制端服务端口号默认为1080</br></br>");
  $("bhead").append('资源同步:&nbsp;&nbsp;<bt id="sync_file">立即执行</bt>');
  $("#sync_file").click(function(){
    var flag = confirm('资源同步:即将同步project目录\n\n是否继续？')
    if (flag){
      http_post("/api/sync_files", {}, null)
    }
  });
  show_agent_list_flush()
}

function show_agent_list_flush(){
  http_post("/api/agent_list", {},
    function show_agent_list(content){
      if (QueryParms.nav != "agent"){
        return
      }
      var text = "<thead><tr><td>编号</td><td>项目</d><td>执行组</td><td>地址</td><td>CPU</td><td>内存</td><td>网卡</td><td>CPU负载</td><td>内存使用</td><td>带宽占用</td><td>状态</td></tr></thead>";
      array = content.data;
      if (array.length == 0){
        return;
      }
      for (i = 0; i < array.length; i++){
        var item = array[i];
        var ready = "失败"
        if (item.ready == 0){
          ready = "未完成"
        }
        else if(item.ready == 2) {
          ready = "准备"
        }
        var row = "<tr id=\"list"+ i + "\"><td>"+i+"</td><td width=100>"+item.project_name+"</td><td width=60>"+item.group_id+"</td><td width=\"200\">"+ item.addr +"</td><td width=\"80\">"+ item.cpu +"核</td>\
        <td width=\"80\">"+ (item.mem/1024).toFixed(2) +"GB</td><td width=\"150\">"+ item.network +"Mbps</td><td width=\"80\">"+ item.cpu_cast +"%</td><td width=\"80\">"+ item.mem_cast +
        "%</td><td width=\"120\">"+ (item.network_cast*8/1024/1024).toFixed(3) +"Mbps</td><td>" + ready +"</td></tr>"
        text = text + row
        $("#list").html(text);
      }
    }
  )
}

function click_nav_about(){
  var text = '\
  访问首页：<a target="_blank" href="https://gitee.com/lutianming/OpenSheeps">https://gitee.com/lutianming/OpenSheeps</a></br>\
  版权所有(c) 2020 lutianming email：641471957@qq.com</br>\
  请勿使用本软件用于破坏信息系统等非法用途，未经授权请勿复制、销售、破解本软件等用于盈利性行为，作者保留一切权利。</br>\
  Copyright(c) 2020 lutianming email：641471957@qq.com</br>\
  Do not use this software for illegal purposes such as destroying the information system. Do not copy, sell or crack this software for profit without authorization. The author reserves all rights.</br>\
  <a href="/supersheeps_ca_pem.crt" target="_blank">下载根证书</a>&nbsp&nbsp&nbsp&nbsp\
  <a href="/SuperSheeps使用手册.html" target="_blank">查看用户手册</a><br>\
  商务合作：软件授权、源码授权、定制开发、解决方案咨询<br>\
  联系方式：QQ641471957  微信wxid_dawnlu 邮箱641471957@qq.com<br>'
  $("bhead").html(text)

  text = '\
  <tr><td><b>用户使用协议</b></td></tr>\
  <tr><td>1.本软件是用于对互联网服务器进行压力测试的工具，完全由作者独立设计和开发，其著作权由作者所有。</td></tr>\
  <tr><td>2.本软件中使用了部分开源项目，其著作权仍然归属原作者。</td></tr>\
  <tr><td>3.用户可以自由选择是否使用本软件，如果用户下载、安装、使用本软件，即表明用户信任本软件。作者对使用本软件时可能对用户自己和他人造成任何形式的损失和伤害不承担任何责任。</td></tr>\
  <tr><td>4.用户可以自由复制、分发和传播本软件的副本用于非盈利性行为，但复制、分发和传播本软件的副本必须真实和完整。</td></tr>\
  <tr><td>5.禁止用户对本软件进行反向工程、反向编译或反向汇编，不得改动编译在程序文件内部的任何资源。</td></tr>\
  <tr><td>6.本软件不包含任何恶意代码或功能，必要时请从作者发布的渠道下载本软件。</td></tr>\
  <tr><td>7.本协议未明示授权的其他权利仍归作者所有，用户使用其他权利时必须获得作者书面同意。</td></tr>\
  \
  <tr><td></td></tr>\
  <tr><td><b>开源项目引用说明</b></td></tr>\
  <tr><td>Sqlite: https://www.sqlite.org</td></tr>\
  <tr><td>cJSON: https://sourceforge.net/projects/cjson</td></tr>\
  <tr><td>KCP: https://github.com/skywind3000/kcp</td></tr>\
  <tr><td>lua: http://www.lua.org</td></tr>\
  <tr><td>sproto: https://github.com/cloudwu/sproto</td></tr>\
  <tr><td>lua-protobuf: https://github.com/starwing/lua-protobuf</td></tr>\
  <tr><td>jQuery: https://jquery.com</td></tr>\
  <tr><td>echarts: https://echarts.apache.org/</td></tr>'
  $("#list").html(text)

}